///*
// * Licensed to the Apache Software Foundation (ASF) under one or more
// * contributor license agreements.  See the NOTICE file distributed with
// * this work for additional information regarding copyright ownership.
// * The ASF licenses this file to you under the Apache License, Version 2.0
// * (the "License"); you may not use this file except in compliance with
// * the License.  You may obtain a copy of the License at
// *
// * http://www.apache.org/licenses/LICENSE-2.0
// *
// * Unless required by applicable law or agreed to in writing, software
// * distributed under the License is distributed on an "AS IS" BASIS,
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// * See the License for the specific language governing permissions and
// * limitations under the License.
// */
//package io.mycat.util;
//
//import com.alibaba.druid.sql.ast.SQLStatement;
//import com.alibaba.druid.sql.ast.statement.SQLInsertInto;
//import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement;
//import io.mycat.Partition;
//import io.mycat.MetaClusterCurrent;
//import io.mycat.MetadataManager;
//import io.mycat.TableHandler;
//import io.mycat.calcite.executor.MycatPreparedStatementUtil;
//import lombok.AllArgsConstructor;
//import lombok.Getter;
//import lombok.ToString;
//import lombok.extern.slf4j.Slf4j;
//
//import java.sql.Connection;
//import java.sql.PreparedStatement;
//import java.sql.ResultSet;
//import java.sql.SQLException;
//import java.util.Arrays;
//import java.util.List;
//import java.util.Objects;
//
//import static java.sql.Statement.NO_GENERATED_KEYS;
//import static java.sql.Statement.RETURN_GENERATED_KEYS;
//
///**
// * 真正要发给后端的sql语句
// * 用于把发送SQL过程中的变量数据内聚到一起， 不需要开发者从各个地方寻找数据。
// * @param <T>
// * @author wangzihaogithub 2020-12-29
// */
//@Slf4j
//@Getter
//@ToString
//@AllArgsConstructor
//public class SQL<T extends SQLStatement> {
//    private String parameterizedSql;
//    private Partition partition;
//    private T statement;
//    private List<Object> parameters;
//
//    public String getTarget() {
//        return partition.getTargetName();
//    }
//
//    public static <T extends SQLStatement> SQL<T> of(String parameterizedSql,
//                                                     Partition partition, T statement, T originStatement, List<Object> parameters){
//        SQL sql;
//        if(statement instanceof SQLUpdateStatement){
//            sql = new UpdateSQL<>(parameterizedSql, partition,(SQLUpdateStatement)statement, (SQLUpdateStatement)originStatement,parameters);
//        }else {
//            sql = new SQL<>(parameterizedSql, partition,statement,parameters);
//        }
//        return sql;
//    }
//
//    public static <T extends SQLStatement> SQL<T> of(String parameterizedSql,
//                                                     Partition partition, T statement, List<Object> parameters){
//        SQL sql;
//            sql = new SQL<>(parameterizedSql, partition,statement,parameters);
//        return sql;
//    }
//
//    public UpdateResult executeUpdate(Connection connection) throws SQLException {
//        return executeUpdate(connection,statement instanceof SQLInsertInto);
//    }
//
//    public UpdateResult executeUpdate(Connection connection,boolean autoGeneratedKeys) throws SQLException {
//        List<Object> parameters = getParameters();
//        if (!parameters.isEmpty()&&parameters.get(0) instanceof List){
//            PreparedStatement preparedStatement = connection.prepareStatement(parameterizedSql, autoGeneratedKeys? RETURN_GENERATED_KEYS : NO_GENERATED_KEYS);
//            for (Object parameter : parameters) {
//                MycatPreparedStatementUtil.setParams(preparedStatement,(List) parameter);
//                preparedStatement.addBatch();
//            }
//            int[] affectedRow = preparedStatement.executeBatch();
//            Long lastInsertId = autoGeneratedKeys? getInSingleSqlLastInsertId(preparedStatement) : null;
//            return new UpdateResult(Arrays.stream(affectedRow).sum(),lastInsertId);
//        }else {
//            PreparedStatement preparedStatement = connection.prepareStatement(parameterizedSql, autoGeneratedKeys? RETURN_GENERATED_KEYS : NO_GENERATED_KEYS);
//            MycatPreparedStatementUtil.setParams(preparedStatement, this.parameters);
//            int affectedRow = preparedStatement.executeUpdate();
//            Long lastInsertId = autoGeneratedKeys? getInSingleSqlLastInsertId(preparedStatement) : null;
//            return new UpdateResult(affectedRow,lastInsertId);
//        }
//
//    }
//
//    /**
//     * ResultSet generatedKeys = preparedStatement.getGeneratedKeys();
//     * 会生成多个值,其中第一个是真正的值
//     *
//     * @param preparedStatement
//     * @return
//     * @throws SQLException
//     */
//    public static Long getInSingleSqlLastInsertId(java.sql.Statement preparedStatement) throws SQLException {
//        Long lastInsertId = null;
//        ResultSet generatedKeys = preparedStatement.getGeneratedKeys();
//        if (generatedKeys != null) {
//            if (generatedKeys.next()) {
//                long generatedKeysLong = generatedKeys.getBigDecimal(1).longValue();
//                if (log.isDebugEnabled()) {
//                    log.debug("preparedStatement:{} insertId:{}", preparedStatement, generatedKeysLong);
//                }
//                lastInsertId = Math.max(generatedKeysLong,0);
//            }
//        }
//        return lastInsertId;
//    }
//
//
//    @Getter
//    @AllArgsConstructor
//    public static class UpdateResult{
//        private int affectedRow;
//        private Long lastInsertId;
//    }
//
//    public TableHandler getTable(){
//        TableHandler table = getMetadataManager().getTable(partition.getSchema(), partition.getTable());
//        return table;
//    }
//
//    public MetadataManager getMetadataManager(){
//        MetadataManager metadataManager = MetaClusterCurrent.wrapper(MetadataManager.class);
//        return metadataManager;
//    }
//
//    @Override
//    public boolean equals(Object o) {
//        if (this == o) {
//            return true;
//        }
//        if (o == null || getClass() != o.getClass()) {
//            return false;
//        }
//        SQL that = (SQL) o;
//        return Objects.equals(that.getTarget(),getTarget())
//                && Objects.equals(that.parameterizedSql,this.parameterizedSql);
//    }
//
//    @Override
//    public int hashCode() {
//        return Objects.hash(this.parameterizedSql,getTarget());
//    }
//}
